package com.mk.util;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import org.osgl.$;
import org.osgl.util.S;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressWarnings("all")
public class S2 {
    private static final String PHONE_REPX = "^(?:0?1)[3456789]\\d{9}$";
    //最大84位
    private static char[] array = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()[]{}:;<>,.|/-=+_€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ"
        .toCharArray();

    public static String getFullError(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
    }

    /**
     * 选举一个非空字符串
     *
     * @param args
     * @return
     */
    public static String electOneNotBlank(String... args) {
        for (String arg : args) {
            if (S.isNotBlank(arg)) return arg;
        }
        return null;
    }

    public static String electOneNotNull(String... args) {
        for (String arg : args) {
            if ($.isNull(arg)) continue;
            return arg;
        }
        return null;
    }

    public static String UUID() {
        return S.uuid().replace("-", "");
    }

    /**
     * 订单号
     *
     * @param fix
     * @return
     */
    public static String buildOrderId(String fix) {
        String orderid = DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN);
        return fix + orderid + String.valueOf(new Double((Math.random() * 8 + 1) * 1000000).intValue());
    }

    public static String appendZero(String src, int size) {
        StringBuilder sb = new StringBuilder(src);
        String zero = "0";
        for (int i = src.length(); i < size; i++) {
            sb.insert(0, zero);
        }
        return sb.length() > size ? sb.substring(sb.length() - size) : sb.toString();
    }

    public static String appendZero(int src, int size) {
        StringBuilder sb = new StringBuilder(String.valueOf(src));
        String zero = "0";
        for (int i = sb.length(); i < size; i++) {
            sb.insert(0, zero);
        }
        return sb.toString();
    }

    public static String repeatWord(int size, String chat) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(chat);
        }
        return sb.toString();
    }

    /**
     * 随机字符串
     *
     * @param length
     * @return
     */
    public static String randomString(int length) {
        Random random = new Random();
        StringBuilder ret = new StringBuilder();
        for (int i = 0; i < length; i++) {
            boolean isChar = (random.nextInt(2) % 2 == 0);// 输出字母还是数字
            if (isChar) { // 字符串
                int choice = random.nextInt(2) % 2 == 0 ? 65 : 97; // 取得大写字母还是小写字母
                ret.append((char) (choice + random.nextInt(26)));
            } else { // 数字
                ret.append(Integer.toString(random.nextInt(10)));
            }
        }
        return ret.toString();
    }

    /**
     * 随机字符串(纯数字)
     *
     * @param size 位数
     * @return
     */
    public static String randomNumberString(int size) {
        int i = (int) ((Math.random() * 9 + 1) * Math.pow(10, (size - 1)));
        return String.valueOf(i);
    }

    /**
     * 字符串拼接 例如 stringBuild("高级黑啊{0},太原热{1}",new String[]{"bay","book"});
     *
     * @param src
     * @param args
     * @return
     */
    public static String stringBuild(String src, String... args) {
        for (int i = 0, j = args.length; i < j; i++)
            src = src.replaceAll("\\{" + i + "}", args[i] + "");
        return src;
    }

    /**
     * 字符串拼接 例如 stringBuild("高级黑啊{name},太原热{age}",{"name":"cc","age":"20"});
     *
     * @param src
     * @param args
     * @return
     */
    public static String stringBuild(String src, Map args) {
        return stringBuild(src, args, false);
    }

    /**
     * 字符串拼接 例如 stringBuild("高级黑啊{name},太原热{age}",{"name":"cc","age":"20"});
     *
     * @param src
     * @param args
     * @param skipIfNotExist
     * @return
     */
    public static String stringBuild(String src, Map args, boolean skipIfNotExist) {
        if (S.isBlank(src)) return src;
        String def = "";
        Pattern p = Pattern.compile("\\{([^}]+)}");
        Matcher m = p.matcher(src);
        StringBuffer buffer = new StringBuffer();
        Dict dict = Dict.create();
        dict.putAll(args);
        while (m.find()) {
            String key = m.group(1);
            Object v = args.getOrDefault(key, null);
            if (v == null) {
                if (skipIfNotExist) continue;
                else v = def;
            }
            m.appendReplacement(buffer, v.toString());
        }
        m.appendTail(buffer);
        return buffer.toString();
    }

    /**
     * 校验手机号的合法性
     *
     * @param phone
     * @return boolean true:手机号正则验证通过，false 手机号格式不正确或手机号为空
     */
    public static boolean phoneValidate(String phone) {
        if (S.isBlank(phone)) {
            return false;
        }
        Pattern pattern = Pattern.compile(PHONE_REPX);
        Matcher matcher = pattern.matcher(phone);
        return matcher.matches();
    }

    /**
     * 模版内容替换为移动端适配
     *
     * @param in
     * @return
     */
    public static String px2rem(String in) {
        Pattern p = Pattern.compile("([0-9.-]+)px", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(in);
        StringBuffer buffer = new StringBuffer();
        while (m.find()) {
            String pxStr = m.group(1);
            Float px = Float.valueOf(pxStr);
            m.appendReplacement(buffer, px / 100 + "rem");
        }
        m.appendTail(buffer);

        p = Pattern.compile("\"width\":\"([0-9-.]+)%\"", Pattern.CASE_INSENSITIVE);
        m = p.matcher(buffer.toString());
        buffer = new StringBuffer();
        while (m.find()) {
            String pxStr = m.group(1);
            m.appendReplacement(buffer, "\"width\":\"" + pxStr + "vw\"");
        }
        m.appendTail(buffer);


        p = Pattern.compile("\"height\":\"([0-9-.]+)%\"", Pattern.CASE_INSENSITIVE);
        m = p.matcher(buffer.toString());
        buffer = new StringBuffer();
        while (m.find()) {
            String pxStr = m.group(1);
            m.appendReplacement(buffer, "\"height\":\"" + pxStr + "vh\"");
        }
        m.appendTail(buffer);
        return buffer.toString();
    }

    /**
     * 模版内容替换为PC编辑适配
     *
     * @param in
     * @return
     */
    public static String rem2px(String in) {
        Pattern p = Pattern.compile("([0-9.-]+)rem", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(in);
        StringBuffer buffer = new StringBuffer();
        while (m.find()) {
            String pxStr = m.group(1);
            Float px = Float.valueOf(pxStr);
            m.appendReplacement(buffer, px * 100 + "px");
        }
        m.appendTail(buffer);

//        if (S.eq(mode, GlobalValues.MODE_PCEDIT.value())) {
        p = Pattern.compile("\"width\":\"([0-9-.]+)vw\"", Pattern.CASE_INSENSITIVE);
        m = p.matcher(buffer.toString());
        buffer = new StringBuffer();
        while (m.find()) {
            String pxStr = m.group(1);
            m.appendReplacement(buffer, "\"width\":\"" + pxStr + "%\"");
        }
        m.appendTail(buffer);


        p = Pattern.compile("\"height\":\"([0-9-.]+)vh\"", Pattern.CASE_INSENSITIVE);
        m = p.matcher(buffer.toString());
        buffer = new StringBuffer();
        while (m.find()) {
            String pxStr = m.group(1);
            m.appendReplacement(buffer, "\"height\":\"" + pxStr + "%\"");
        }
        m.appendTail(buffer);
//        }
        return buffer.toString();
    }

    public static String tenTo2cf(long num, int N) {
        Stack<Character> stack = new Stack<>();
        StringBuilder result = new StringBuilder(0);
        while (num != 0) {
            stack.add(array[new Long((num % N)).intValue()]);
            num = num / N;
        }
        for (; !stack.isEmpty(); ) {
            result.append(stack.pop());
        }
        return result.length() == 0 ? "0" : result.toString();
    }

    public static String replaceReg(String src, String reg, String with) {
        if (S.isBlank(src)) return src;
        return src.replaceAll(reg, with);
    }

    /**
     * 生成多进制字符串
     * 最高支持的进制数
     *
     * @param num
     * @return
     */
    public static String tenToH2cf(long num) {
        return tenTo2cf(num, array.length);
    }

    /**
     * 生成随机数
     *
     * @param length        生成位数
     * @param maxsamelength 最大相同的
     * @return
     */
    public static Long createRandomNum(int length, int maxsamelength) {
        Long result = RandomUtil.randomLong(Math.round(Math.pow(10, length - 1)), Math.round(Math.pow(10, length)));
        if (matchSameLength(result.toString(), maxsamelength)) {
            return createRandomNum(length, maxsamelength);
        }
        return result;
    }

    /**
     * 查看src中连续相同数字的是否达到maxsamelength个
     *
     * @param src
     * @param maxsamelength
     * @return
     */
    public static Boolean matchSameLength(String src, int maxsamelength) {
        Pattern pattern = Pattern.compile("\\d*([\\d])\\1{" + (maxsamelength) + "," + (src.length() - 1) + "}\\d*");
        Matcher matcher = pattern.matcher(src);
        return matcher.matches();
    }

    /**
     * 生成提货码
     * 90000~100000个左右
     *
     * @param prenum
     * @param maxsamelength
     * @return
     */
    public static List<String> createTrcodes(String prenum, int maxsamelength) {
//        100000
        List<Integer> list = new ArrayList<>();
        //生成所有核销码
        for (int i = 0; i < 100000; i++) {
            list.add(i);
        }
        List<String> result = new ArrayList<>();
        while (list.size() > 0) {
            Integer remove = list.remove(RandomUtil.randomInt(list.size()));
            String insert = (Integer.parseInt(prenum) * 100000 + remove) + "";
            if (maxsamelength < insert.length()) {
                if (!matchSameLength(insert, maxsamelength)) {
                    result.add(insert);
                }
            } else {
                result.add(insert);
            }
        }
        return result;
    }

    /**
     * 生成核销码
     *
     * @return
     */
    public static String createTrcode() {
        return S2.tenTo2cf(Thread.currentThread().getId() + System.nanoTime(), 16);
    }
}
